/**
 * Author : Fengyuan(Franklin) Zhang
 * Date : 2018/12/28
 * Description : Index router
 */

var fs = require('fs');
var formidable = require('formidable');
var uuid = require('uuid');
var request = require('request');
var DataCtrl = require('../controls/data');
var CommonMethod = require('../utils/commonMethod');
var Setting = require('../setting');


module.exports = function(app){
  
  //! ping URL
  app.route('/ping')
    .get(function(req, res, next){
      res.end('OK');
    });

  
  //! checking init URL
  app.route('*')
    .get(function(req, res, next){
      if(global.Inited){
        next();
      }
      else{
        return res.end(JSON.stringify({
          result : 'err',
          code : -10,
          message : 'Initializing... Please wait for minites...',
          data : ''
        }));
      }
    })
    .post(function(req, res, next){
      if(global.Inited){
        next();
      }
      else{
        return res.end(JSON.stringify({
          result : 'err',
          code : -10,
          message : 'Initializing... Please wait for minites...',
          data : ''
        }));
      }
    });

  
  //! uploading
  app.route('/data')
    .get(function(req, res, next){
      if(req.query.md5){
        var md5 = req.query.md5;
        DataCtrl.getByMD5(String(md5), function (err, items) {
          if(err){
            return res.end(JSON.stringify({
              result : 'err',
              code : -1,
              message : err.message,
              data : ''
            }));
          }
          if(!items.length || items.length == 0){
            return res.end(JSON.stringify({
              result : 'suc',
              code : 0,
              message : '',
              data : ''
            }));
          }
          else{
            var item = items[0];
            var d_pwd_c = CommonMethod.crypto(CommonMethod.crypto(item.d_pwd));
            DataCtrl.refresh(item, function (err, result) {});
            return res.end(JSON.stringify({
              result : 'suc',
              code : 1,
              message : '',
              data : {
                id : items[0]._id,
                d_pwd : d_pwd_c
              }
            }));
          }
        });
      }
      else{
        next();
      }
    })
    .post(function(req, res, next){
      if(global.TotalSize > Setting.maxCapacity){
        return res.end(JSON.stringify({
          result : 'err',
          code : -5,
          message : 'No more capacity!',
          data : ''
        }));
      }
      var form = new formidable.IncomingForm();
      form.encoding = 'utf-8';
      form.uploadDir = Setting.filePath;
      form.keepExtensions = true;
      form.maxFieldsSize = 2048 * 1024 * 1024;
      form.parse(req, function (err, fields, files) {
        if(err){
          return res.end(JSON.stringify({
            result : 'err',
            code : -1,
            message : err.message,
            data : ''
          }));
        }
        if(!files.datafile){
          return res.end(JSON.stringify({
            result : 'err',
            code : -2,
            message : 'No data file found!',
            data : ''
          }));
        }
        fs.stat(files.datafile.path, function(err, fstat) {
          if(err){
            return res.end(JSON.stringify({
              result : 'err',
              code : -3,
              message : err.message,
              data : ''
            }));
          }
          var pwd = '';
          if(fields.pwd && fields.pwd == 'true'){
            pwd = uuid.v1();
          }
          var data = {
            d_tag : fields.datatag,
            d_size : fstat.size,
            d_pwd : pwd
          }
          data.datafile = files.datafile.path;
          DataCtrl.add(data, function(err, result) {
            if(err){
              return res.end(JSON.stringify({
                result : 'err',
                code : -4,
                message : err.message,
                data : ''
              }));
            }
            if(pwd != ''){
              pwd = CommonMethod.crypto(CommonMethod.crypto(pwd));
            }
            return res.end(JSON.stringify({
              result : 'suc',
              code : 1,
              message : '',
              data : {
                id : result._id,
                d_pwd : pwd
              }
            }));
          });
        });
      });
    });
  
  //! downloading
  app.route('/data/:id')
    .get(function(req, res, next){
      var ac = req.query.ac;
      var oid = req.params.id;
      if(ac == 'check'){
        DataCtrl.getByOID(oid, function (err, data) {
          if(err){
            return res.end(JSON.stringify({
              result : 'err',
              code : -1,
              message : err.message,
              data : ''
            }));
          }
          if(data == null){
            return res.end(JSON.stringify({
              result : 'err',
              code : -2,
              message : 'No such data!',
              data : ''
            }));
          }
          DataCtrl.refresh(data, function (err, result) {});
          return res.end(JSON.stringify({
            result : 'suc',
            code : 1,
            message : '',
            data : data._id
          }));
        });
      }
      else{
        DataCtrl.getByOID(oid, function (err, data) {
          if(err){
            return res.end(JSON.stringify({
              result : 'err',
              code : -2,
              message : err.message,
              data : ''
            }));
          }
          if(data == null){
            return res.end(JSON.stringify({
              result : 'err',
              code : -2,
              message : 'No such data!',
              data : ''
            }));
          }
          if(data.d_pwd != ''){
            if(req.query.pwd == undefined || req.query.pwd == null || req.query.pwd.trim() == ''){
              return res.end(JSON.stringify({
                result : 'err',
                code : -4,
                message : 'No permission!',
                data : ''
              }));
            }
            var pwd = CommonMethod.decrypto(req.query.pwd);
            if(pwd != data.d_pwd){
              return res.end(JSON.stringify({
                result : 'err',
                code : -4,
                message : 'No permission!',
                data : ''
              }));
            }
          }
          DataCtrl.refresh(data, function (err, result) {});
          fs.readFile(data.d_fullpath, function (err, filecontent) {
            if(err){
              DataCtrl.removeDbItem(oid);
              return res.end(JSON.stringify({
                result : 'err',
                code : -3,
                message : err.message,
                data : ''
              }));
            }
            //! find extension
            var ext = data.d_fullpath;
            ext = ext.substr(ext.lastIndexOf('.') + 1);

            //! make up file name
            var filename = data.d_tag;
            if(filename.trim() == ''){
              filename = data._id.toString();
            }

            //! mark data as requested
            DataCtrl.markDataAsRequested(data, function (err, result) {
              if(err){
                console.log('Error in mark data as requested! : ' + err.message);
              }
              res.set({
                  'Content-Type': 'file/*',
                  'Content-Length': data.d_size });
              res.setHeader('Content-Disposition', 'attachment; filename=' + encodeURIComponent(filename + '.' + ext));
              res.end(filecontent);
            });
          });
        });
      }
    });

  //! register
  app.route('/registration')
    .get(function(req, res, next){
      var host = req.query.host;
      var port = req.query.port;
      request.post('http://' + host + ':' + port + '/dxserver', 
      {
        form : {"port" : "8062"}
      }, function (err, response) {
        if(err){
          res.end('Error' + JSON.stringify(err));
        }
        var resJson = JSON.parse(response.body);
        if(resJson['result'] == 'suc'){
          res.end('Suc');
        }
      });
    });

  //! unknown URL
  app.route('*')
    .get(function(req, res, next){
      return res.end(JSON.stringify({
        result : 'err',
        code : -9,
        message : 'Unknown API',
        data : ''
      }));
    })
    .post(function(req, res, next){
      return res.end(JSON.stringify({
        result : 'err',
        code : -9,
        message : 'Unknown API',
        data : ''
      }));
    });
};
